﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace _4Gewinnt
{
    /// <summary>
    /// Performs a single match
    /// </summary>
    public class GameController
    {
        //The GUI to display the stuff
        private _4gewinnt_GUI GUI;
        /// <summary>
        /// The current game
        /// </summary>
        public Game game;
        /// <summary>
        /// The players
        /// </summary>
        public Engine activePlayer, passivePlayer;
        /// <summary>
        /// The number of token in a row needed to win
        /// </summary>
        private int ttw = 4;
        /// <summary>
        /// Show game board while playing (Messages are shown anyway)
        /// </summary>
        public bool ShowBoardInGUI = true;

        /// <summary>
        /// Initializes the game controller
        /// </summary>
        /// <param name="GUI">The GUI to display the stuff</param>
        public GameController(_4gewinnt_GUI GUI)
        {
            this.GUI = GUI;
        }

        /// <summary>
        /// Starts a new game
        /// </summary>
        /// <param name="activePlayer">The active player is the start player</param>
        /// <param name="passivePlayer">The opponent</param>
        public void startGame(Engine activePlayer, Engine passivePlayer)
        {
            this.activePlayer = activePlayer;
            this.passivePlayer = passivePlayer;

            //init game
            initGame();

            //run game
            runGame();
        }

                /// <summary>
        /// Initializes a new game
        /// </summary>
        private void initGame()
        {
            //start new game
            game = new Game(activePlayer.Me, ttw);

            //redraw board;
            if (ShowBoardInGUI)
                GUI.drawBoard(this);

            //show player names in GUI
            if (activePlayer.Me == GameColor.Red)
                GUI.showPlayerNames(activePlayer, passivePlayer);
            else
                GUI.showPlayerNames(passivePlayer, activePlayer);

            //show some game messages
            GUI.gameMessage("---------------");
            GUI.gameMessage("Neues Spiel...");
            GUI.gameMessage(activePlayer.ToString() + " spielt mit " + activePlayer.Me.ToString());
            GUI.gameMessage(passivePlayer.ToString() + " spielt mit " + passivePlayer.Me.ToString());
        }


        /// <summary>
        /// Runs the main game loop
        /// </summary>
        private void runGame()
        {
            //start game
            while (1 == 1)
            {
                //mark active player in GUI
                if (ShowBoardInGUI)
                    GUI.showActivePlayer(activePlayer.Me);

                //let active player move
                int move = activePlayer.makeMove();
                game.makeMove(move);

                //let active player say something
                if (ShowBoardInGUI)
                    GUI.engineMessage(activePlayer.say());

                //draw move
                if (ShowBoardInGUI)
                    GUI.drawBoard(this);

                //tell passive player active player's move
                passivePlayer.update(move);

                //stop game on win or draw
                if (game.HasWon || game.Draw)
                    break;

                //switch active players
                switchActivePlayer();
            }

            //if active player won:
            if (game.HasWon)
            {
                if (ShowBoardInGUI)
                    GUI.drawWinningPosition(this, game.winningPosition, activePlayer.Me);
                GUI.gameMessage(activePlayer.GetType().ToString() + "(" + activePlayer.Me.ToString() + ") hat gewonnen.");
            }
            //if draw:
            else
            {
                GUI.gameMessage("Unentschieden.");
            }
        }


        /// <summary>
        /// Switches the active player
        /// </summary>
        private void switchActivePlayer()
        {
            Engine tmp = activePlayer;
            activePlayer = passivePlayer;
            passivePlayer = tmp;
        }



    }   
}
